﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using ImageProcessing.Utility;

namespace ImageReview
{
    public partial class BatchProcess : System.Web.UI.Page
    {
        private static List<string> _files = new List<string>();
        private static string _batchOutputFolder = ConfigurationManager.AppSettings["batchOutput"];
        private static string _batchUploadFolder = ConfigurationManager.AppSettings["batchUpload"];
        //step 1. Load all images in the batch_output folder, count the total number of images on page load
        protected void Page_Load(object sender, EventArgs e)
        {

            string username = User.Identity.Name;
            username = username.Substring(username.LastIndexOf('\\') + 1);
            if(username.Contains("swu"))
            {
                btnUpdateDatabase.Visible = true;
            }
            else
            {
                btnUpdateDatabase.Visible = false;
            }
            this.fsOutput.Visible = false;

            LoadFiles();
        }

        private void LoadFiles()
        {
            _files.Clear();
            string[] files = Directory.GetFiles(_batchOutputFolder, "*.jpg", SearchOption.AllDirectories);
            _files.AddRange(files);
            lblMessage.Text = files.Length.ToString();
            LogEvent("files in batch output folder is loaded.");
        }


        private void LogEvent(string description)
        {
            EventLog.WriteEntry("Application",description, EventLogEntryType.Information);
        }
        protected void btnBatchProcess_Click(object sender, EventArgs e)
        {

            string basedir = ConfigurationManager.AppSettings["basedir"];
            string archivedir = ConfigurationManager.AppSettings["archivedir"];
            string importdir = ConfigurationManager.AppSettings["importdir"];
            string dbname = ConfigurationManager.AppSettings["dbname"];

            LogEvent("Start Process at " + DateTime.Now.ToString());

            DateTime start = DateTime.Now;
            LoadFiles();
            if(_files.Count ==0)
            {
                lblMessage.Text = "No file loaded.";
                return;
            }
            ImagesHandler handler = new ImagesHandler(basedir,importdir,archivedir,dbname);

            LogEvent("Image handler loaded successfullly.");
            bool uploadToMOSS = chkEnableFTP.Checked;

            //Retrieve all images and name image name to two suffix if its currently one suffix
            RetrieveAndRename(uploadToMOSS);

            TimeSpan uploadTime;
            bool enableArchive = chkEnableArchive.Checked;

            bool success = handler.BatchProcessToMD5AndArchiveToTimeFolder(uploadToMOSS, enableArchive, _batchOutputFolder, _batchUploadFolder, out uploadTime);
            if (success)
            {
                if (uploadTime.TotalSeconds > 60)
                this.lblFTPTime.Text = uploadTime.TotalMinutes + " minutes";
                else
                    this.lblFTPTime.Text = uploadTime.TotalSeconds + " seconds";
                DateTime finish = DateTime.Now;
                TimeSpan duration = finish - start;
                if (duration.TotalSeconds > 60)
                    this.lblTimeSpent.Text = duration.TotalMinutes + " minutes";
                else
                    this.lblTimeSpent.Text = duration.TotalSeconds + " seconds";

                DeleteAllImagesInBatchOutput();
                DeleteAllImagesInBatchUpload();
                this.fsOutput.Visible = true;
                lblStatus.Text = "All Images are processed successfully!<br>To check the processed images, go to <a href='search.aspx'>Search Page</a>.";
            }
            else
            {
                this.fsOutput.Visible = true;
                lblStatus.Text = "Error occurs on Processing Images and Uploading to SharePoint, please check Event Viewer for details.";
            }
        }
        private string GetFileName(string file)
        {
            string filename = file.Substring(file.LastIndexOf('\\') + 1, file.Length - file.LastIndexOf('\\') - 1);
            return filename;
        }

        //retrieve all images 
        private void RetrieveAndRename(bool isUploadToMOSS)
        {
            LogEvent("Start retrieve and rename images.");
            foreach (string file in _files)
            {
                string filename = GetFileName(file);
                if (filename.EndsWith(".jpg", StringComparison.CurrentCultureIgnoreCase))
                {
                    filename = filename.Substring(0, filename.LastIndexOf("."));
                }

                string goodid, suffix;
                GetGoodIdAndSuffix(filename, out goodid, out suffix);
                if (!_batchUploadFolder.EndsWith("\\"))
                    _batchUploadFolder += "\\";
                //rename (copy and delete old) file is only one suffix
                if(suffix.Length == 1)
                {
                    string newFile = file.Replace(goodid + suffix, goodid + "a" + suffix);
                    File.Copy(file,newFile,true);
                    if(isUploadToMOSS)
                    {
                         string uploadFilePath = _batchUploadFolder + goodid + suffix + ".jpg";
                        File.Move(file, uploadFilePath);                       
                    }else
                    {
                        File.Delete(file);
                    }
                }
                if(suffix.Length == 2)
                {
                    if(isUploadToMOSS)
                    {
                        string uploadFilePath = _batchUploadFolder + goodid + suffix[1] + ".jpg";
                        File.Copy(file,uploadFilePath, true); 
                    }
                    
                }
            }
            LogEvent("Retrieve and rename finished.");
        }
        private void GetGoodIdAndSuffix(string input, out string goodId, out string suffix)
        {
            goodId = string.Empty;
            suffix = string.Empty;
            string pattern = @"^(\d+)([A-Za-z]+)$";

            Match match = Regex.Match(input, pattern);
            if (match.Success)
            {
                goodId = match.Groups[1].Value;
                suffix = match.Groups[2].Value;
            }
        }

        private void DeleteAllImagesInBatchOutput()
        {

            string batchOutput = ConfigurationManager.AppSettings["batchOutput"];
            DirectoryInfo di = new DirectoryInfo(batchOutput);
            
            List<string> files = new List<string>();
            try
            {
                //delete all files in root
                foreach (FileInfo item in di.GetFiles())
                {
                    files.Add(item.FullName);
                }
                foreach (string item in files)
                {
                    File.Delete(item);
                }
                //delete all folders recursively in root
                List<string> subFolders = new List<string>();
                foreach ( DirectoryInfo directory in di.GetDirectories())
                {
                    subFolders.Add(directory.FullName); 
                }
                foreach (string subFolder in subFolders)
                {
                    Directory.Delete(subFolder,true);
                }
            }
            catch (Exception ex)
            {
                Response.Write(string.Format("<script type=\"text/javascript\">alert('Directory {0} \n could not be accessed!');</script>", di.FullName));
                return;
            }
        }
        private void DeleteAllImagesInBatchUpload()
        {

            DirectoryInfo di = new DirectoryInfo(_batchUploadFolder);

            List<string> files = new List<string>();
            try
            {
                //delete all files in root
                foreach (FileInfo item in di.GetFiles())
                {
                    files.Add(item.FullName);
                }
                foreach (string item in files)
                {
                    File.Delete(item);
                }
                //delete all folders recursively in root
                List<string> subFolders = new List<string>();
                foreach (DirectoryInfo directory in di.GetDirectories())
                {
                    subFolders.Add(directory.FullName);
                }
                foreach (string subFolder in subFolders)
                {
                    Directory.Delete(subFolder, true);
                }
            }
            catch (Exception ex)
            {
                Response.Write(string.Format("<script type=\"text/javascript\">alert('Directory {0} \n could not be accessed!');</script>", di.FullName));
                return;
            }
        }

        protected void btnUpdateDatabase_Click(object sender, EventArgs e)
        {
            string basedir = ConfigurationManager.AppSettings["basedir"];
            string archivedir = ConfigurationManager.AppSettings["archivedir"];
            string importdir = ConfigurationManager.AppSettings["importdir"];
            string dbname = ConfigurationManager.AppSettings["dbname"];

            ImagesHandler handler = new ImagesHandler(basedir, importdir, archivedir, dbname);
            if(!basedir.EndsWith("\\"))
                basedir += "\\";
            string processedImageFolder = string.Format("{0}processed", basedir);
            handler.UpdateDatabaseFromProcessedImages(processedImageFolder);
        }
    }
}